﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.Windows.Threading;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using SlChatClient.Helper;
using TestServices.Model;
using SlChatClient.ChatServices;
using SlChatClient.Services;

namespace SlChatClient.ViewModel
{
    /// <summary>
    /// This class contains properties that the main View can data bind to.
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class MainViewModel : ViewModelBase
    {
        private string _userName;

        public string UserName
        {
            get
            {
                return _userName;
            }
            set
            {
                _userName = value;
                base.RaisePropertyChanged("UserName");
            }
        }

        private string _password;

        public string Password
        {
            get
            {
                return _password;
            }
            set
            {
                _password = value;
                base.RaisePropertyChanged("Password");
            }
        }



        private bool _isSignIn;

        public bool IsSignIn
        {
            get
            {
                return _isSignIn;
            }
            set
            {
                _isSignIn = value;
                base.RaisePropertyChanged("IsSignIn");
            }
        }



        private ObservableCollection<User> _friendList;

        public ObservableCollection<User> FriendList
        {
            get
            {
                return _friendList;
            }
            set
            {
                _friendList = value;
                base.RaisePropertyChanged("FriendList");
            }
        }


        private User _selectedUser;

        public User SelectedUser
        {
            get
            {
                return _selectedUser;
            }
            set
            {
                _selectedUser = value;
                if (value != null && this.ChatStrings != null && this.ChatStrings.ChatContents.Count > 0)
                {
                    this.ChatStrings.ChatContents.Clear();
                }
                base.RaisePropertyChanged("SelectedUser");
            }
        }



        private string _chatStringContent;

        public string ChatStringContent
        {
            get
            {
                return _chatStringContent;
            }
            set
            {
                _chatStringContent = value;
                base.RaisePropertyChanged("ChatStringContent");
            }
        }



        private ChatStrings _chatStrings;

        public ChatStrings ChatStrings
        {
            get
            {
                return _chatStrings;
            }
            set
            {
                _chatStrings = value;
                base.RaisePropertyChanged("ChatStrings");
            }
        }


        private DispatcherTimer _timer;
        private User _currentUser;
        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            _timer = new DispatcherTimer();
            _timer.Interval = new TimeSpan(0, 0, 0, 0, 20);
            _timer.Tick += new EventHandler(timer_Tick);

            this.IsSignIn = false;
            Proxy.ProxyClient.CheckLoginCompleted += new EventHandler<CheckLoginCompletedEventArgs>(ProxyClient_CheckLoginCompleted);
            Proxy.ProxyClient.GetFriendCompleted += new EventHandler<GetFriendCompletedEventArgs>(ProxyClient_GetFriendCompleted);
            Proxy.ProxyClient.GetChatContentCompleted += new EventHandler<GetChatContentCompletedEventArgs>(ProxyClient_GetChatContentCompleted);
            Proxy.ProxyClient.CreateNewChatContentCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(ProxyClient_CreateNewChatContentCompleted);
            Proxy.ProxyClient.CreateNewUserCompleted += new EventHandler<CreateNewUserCompletedEventArgs>(ProxyClient_CreateNewUserCompleted);
            Proxy.ProxyClient.UpdateChatContentCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(ProxyClient_UpdateChatContentCompleted);
            Proxy.ProxyClient.UpdateOfflineUserCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(ProxyClient_UpdateOfflineUserCompleted);
        }

        void ProxyClient_UpdateOfflineUserCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            //throw new NotImplementedException();
        }

        void ProxyClient_UpdateChatContentCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            //throw new NotImplementedException();
        }

        void ProxyClient_CreateNewUserCompleted(object sender, CreateNewUserCompletedEventArgs e)
        {
            this._currentUser = e.Result;
            this.IsSignIn = true;
            this._timer.Start();
        }

        void ProxyClient_CreateNewChatContentCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            //throw new NotImplementedException();
        }

        void ProxyClient_GetChatContentCompleted(object sender, GetChatContentCompletedEventArgs e)
        {
            string contents = e.Result;
            if (!string.IsNullOrWhiteSpace(contents))
            {
                var chatStrings = Serializer<ChatStrings>.Deserialize(contents);
                if (this.ChatStrings == null || this.ChatStrings.ChatContents.Count == 0)
                {
                    this.ChatStrings = chatStrings;
                }
                else
                {
                    if (chatStrings.ChatContents.Count > this.ChatStrings.ChatContents.Count)
                    {
                        for (int index = this.ChatStrings.ChatContents.Count; index < chatStrings.ChatContents.Count; index++)
                        {
                            var chatContent = chatStrings.ChatContents[index];
                            this.ChatStrings.ChatContents.Add(chatContent);
                        }
                    }
                }
            }
        }

        void ProxyClient_GetFriendCompleted(object sender, GetFriendCompletedEventArgs e)
        {
            var friends = e.Result;
            if (this.FriendList == null || this.FriendList.Count == 0)
            {
                this.FriendList = friends;
            }
            else if (this.FriendList.Count != friends.Count)
            {
                this.FriendList = friends;
            }

            if (this.SelectedUser != null)
            {
                Proxy.ProxyClient.GetChatContentAsync(this._currentUser.UserPK, this.SelectedUser.UserPK);
            }
        }

        void ProxyClient_CheckLoginCompleted(object sender, CheckLoginCompletedEventArgs e)
        {
            if (e.Result != null)
            {
                this._currentUser = e.Result;
                this.IsSignIn = true;
                this._timer.Start();
            }
            else
            {
                Proxy.ProxyClient.CreateNewUserAsync(this.UserName, this.Password);
            }
        }

        void timer_Tick(object sender, EventArgs e)
        {
            Proxy.ProxyClient.GetFriendAsync(this._currentUser.UserPK);
        }

        private ICommand _logInCommand;

        public ICommand LogInCommand
        {
            get
            {
                return this._logInCommand ?? (this._logInCommand = new RelayCommand<object>(this.ExecuteLogInCommand));
            }
        }

        private void ExecuteLogInCommand(object commandParam)
        {
            Proxy.ProxyClient.CheckLoginAsync(this.UserName, this.Password);

        }



        private ICommand _sendChatCommand;

        public ICommand SendChatCommand
        {
            get
            {
                return this._sendChatCommand ?? (this._sendChatCommand = new RelayCommand<object>(this.ExecuteSendChatCommand));
            }
        }

        private void ExecuteSendChatCommand(object commandParam)
        {
            if (this.ChatStrings == null || this.ChatStrings.ChatContents.Count == 0)
            {
                this.ChatStrings = new ChatStrings();
                this.ChatStrings.ChatContents = new List<ChatString>();
                ChatString chatString = new ChatString()
                {
                    ChatContent = this.ChatStringContent,
                    ChatDateTime = DateTime.Now,
                    UserName = this._currentUser.UserName
                };
                this.ChatStrings.ChatContents.Add(chatString);
                string chatS = Serializer<TestServices.Model.ChatStrings>.Serialize(this.ChatStrings);
                Proxy.ProxyClient.CreateNewChatContentAsync(this._currentUser.UserPK, this.SelectedUser.UserPK, chatS);
            }
            else
            {
                ChatString chatString = new ChatString()
                {
                    ChatContent = this.ChatStringContent,
                    ChatDateTime = DateTime.Now,
                    UserName = this._currentUser.UserName
                };
                this.ChatStrings.ChatContents.Add(chatString);
                string chatS = Serializer<TestServices.Model.ChatStrings>.Serialize(this.ChatStrings);
                Proxy.ProxyClient.UpdateChatContentAsync(this._currentUser.UserPK, this.SelectedUser.UserPK, chatS);
            }

            this.ChatStringContent = string.Empty;
        }



        private ICommand _closeCommand;

        public ICommand CloseCommand
        {
            get
            {
                return this._closeCommand ?? (this._closeCommand = new RelayCommand<object>(this.ExecuteCloseCommand));
            }
        }

        private void ExecuteCloseCommand(object commandParam)
        {
            if (this._currentUser != null)
            {
                Proxy.ProxyClient.UpdateOfflineUserAsync(this._currentUser.UserPK);
            }
        }



        private ICommand _TextChangedCommand;

        public ICommand TextChangedCommand
        {
            get
            {
                return this._TextChangedCommand ?? (this._TextChangedCommand = new RelayCommand<object>(this.ExecuteTextChangedCommand));
            }
        }

        private void ExecuteTextChangedCommand(object commandParam)
        {
            this.Password = commandParam.ToString();
        }



        private ICommand _keyDownCommand;

        public ICommand KeyDownCommand
        {
            get
            {
                return this._keyDownCommand ?? (this._keyDownCommand = new RelayCommand<KeyEventArgs>(this.ExecuteKeyDownCommand));
            }
        }

        private void ExecuteKeyDownCommand(KeyEventArgs commandParam)
        {
            // TODO: implement code
            if (commandParam.Key == Key.Enter)
            {
                this.SendChatCommand.Execute(null);
            }
        }




        ////public override void Cleanup()
        ////{
        ////    // Clean up if needed

        ////    base.Cleanup();
        ////}
    }
}